package cn.lsoft.undoner.service.pay.impl;

import java.beans.IntrospectionException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.util.Hashtable;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import cn.lsoft.undoner.controller.pay.PayController;
import cn.lsoft.undoner.model.pay.MerchantData;
import cn.lsoft.undoner.model.pay.QrcodeRetData;
import cn.lsoft.undoner.service.pay.PayService;
import cn.lsoft.undoner.util.Md5Util;
import cn.lsoft.undoner.util.MerchantCache;
import cn.lsoft.undoner.util.QrcodeImgCreator;
import cn.lsoft.undoner.util.StringUtil;
import cn.lsoft.undoner.util.BeanUtil;
@Service
public class PayServiceImpl implements PayService{
	private static final Logger logger = LoggerFactory.getLogger(PayServiceImpl.class);
	private static final String qrcodeUrlBase = "http://127.0.0.1:8080/images/";
	private static final String payRequestUrl = "http://127.0.0.1:8080/UnionPayApi/pay/order";
	private static final String qrcodeLocalDir = "E:\\apache-tomcat-7.0.42\\webapps\\images\\";//本地二维码存放地址
	private Gson gson = new Gson ();
	@Override
	public QrcodeRetData acceptPay(MerchantData merchantMessage) {
		
		String a_token = StringUtil.getRandomStringByLength(20);
		//将请求地址生成二维码图片
		String qrcodeValue = payRequestUrl + "?a_token=" + a_token;	//二维码图片实际存放的数据
		String qrcodeImgName = QrcodeImgCreator.generateImg(qrcodeValue , qrcodeLocalDir);	//生成的二维码图片名称
		String qrcode = qrcodeUrlBase + qrcodeImgName;		//远程网络访问地址
		
		QrcodeRetData qrcodeRetData = new QrcodeRetData();
		qrcodeRetData.setQrcode(qrcode);
		qrcodeRetData.setQrcodeVal(qrcodeValue);
		qrcodeRetData.setSuccessful("SUCCESS");
		qrcodeRetData.setErrorMsg("");
		
		//模拟将支付请求信息写入缓存中/DB。
		Hashtable<String,MerchantData> merchantCache = MerchantCache.getInstance().merchantCacheHash;
		if(!merchantCache.contains(a_token)){
			merchantCache.put(a_token, merchantMessage);
		}
		for (Map.Entry<String, MerchantData> entry : MerchantCache.getInstance().merchantCacheHash.entrySet()) {
			logger.debug("puy	: Key = " + entry.getKey() + ", Value = " + entry.getValue().toString());
		}
		return qrcodeRetData;
	}

	@Override
	public String unionPay(MerchantData merchantMessage) {
		String payType = merchantMessage.getPayType();
		
		//根据payType值调用不同的支付接口
		//doSomeThing();
		
		//记录流程日志
		//doSomeThing();

		return merchantMessage.toString();
	}

	@Override
	public boolean isValidMd5Parameter(MerchantData merchantMessage) throws IllegalAccessException, InvocationTargetException, UnsupportedEncodingException, IntrospectionException {
		Map requestParams = null; 
		String inputCharset = merchantMessage.getInputCharset();
		requestParams = BeanUtil.convertObj2Map(merchantMessage, inputCharset);
		String signValue = merchantMessage.getSignValue();
		
		//模拟从DB中取得商务注册时分配的秘钥:key
		String key = "fe55b3f461394242a95858a8b6cbfd2d";
		
		//去除请求参数中的sign与sign_type
		requestParams = BeanUtil.paraFilter(requestParams);
		//将请求参数按ASIC码的顺序拼接为一个字符串
		String verifyStr = BeanUtil.createLinkString(requestParams);
		//MD5校验
		logger.info("MD5校验,商户请求MD5 数据:" + verifyStr);
		boolean md5VerifyResult;
		md5VerifyResult = Md5Util.verify(verifyStr, signValue, key, inputCharset);
		if (!md5VerifyResult){
			return false;
		}else{
			return true;
		}
	}

	@Override
	public MerchantData acceptOrder(String a_token) {
		logger.info("a_token = " + a_token);
		MerchantData merchantMessage = null;
		
		//模拟从缓存/DB中把相应的支付请求信息取出。
		Hashtable<String,MerchantData> merchantCache = MerchantCache.getInstance().merchantCacheHash;
		if(merchantCache.containsKey(a_token)){
			merchantMessage = merchantCache.get(a_token);
		}else{
			//doSomeThing();
			logger.error("请求丢失:"+a_token);
			return null;
		}
	
		//对订单是否重复支付进行校验
		//doSomeThing();
		
		//记录流程日志
		//doSomeThing();
		logger.info("merchantMessage:"+merchantMessage.toString());
		return merchantMessage;
	}

}
